﻿Imports System
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Drawing.Design
Imports System.Globalization
Imports System.Reflection
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Design

Namespace System.Workflow.ComponentModel
    <SRDescription("FaultActivityDescription"), ToolboxBitmap(GetType(ThrowActivity), "Resources.Throw.png"), Designer(GetType(ThrowDesigner), GetType(IDesigner)), ToolboxItem(GetType(ActivityToolboxItem)), SRCategory("Standard")> _
    Public NotInheritable Class ThrowActivity
        Inherits Activity
        Implements ITypeFilterProvider, IDynamicPropertyTypeProvider
        ' Methods
        Public Sub New()
        End Sub

        Public Sub New(ByVal name As String)
            MyBase.New(name)
        End Sub

        Protected Friend NotOverridable Overrides Function Execute(ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If ((Me.Fault Is Nothing) AndAlso (Me.FaultType Is Nothing)) Then
                Throw New InvalidOperationException(SR.GetString(CultureInfo.CurrentCulture, "Error_PropertyNotSet", New Object() { ThrowActivity.FaultProperty.Name }))
            End If
            If ((Not Me.FaultType Is Nothing) AndAlso Not GetType(Exception).IsAssignableFrom(Me.FaultType)) Then
                Throw New InvalidOperationException(SR.GetString(CultureInfo.CurrentCulture, "Error_ExceptionTypeNotException", New Object() { Me.FaultType, ThrowActivity.FaultTypeProperty.Name }))
            End If
            If (((Not Me.Fault Is Nothing) AndAlso (Not Me.FaultType Is Nothing)) AndAlso Not Me.FaultType.IsInstanceOfType(Me.Fault)) Then
                Throw New InvalidOperationException(SR.GetString(CultureInfo.CurrentCulture, "Error_FaultIsNotOfFaultType"))
            End If
            If (Not Me.Fault Is Nothing) Then
                Throw Me.Fault
            End If
            Dim constructor As ConstructorInfo = Me.FaultType.GetConstructor(New Type(0  - 1) {})
            If (Not constructor Is Nothing) Then
                Throw DirectCast(constructor.Invoke(Nothing), Exception)
            End If
            Throw New InvalidOperationException(SR.GetString(CultureInfo.CurrentCulture, "Error_FaultTypeNoDefaultConstructor", New Object() { Me.FaultType }))
        End Function

        Protected Friend Overrides Sub Initialize(ByVal provider As IServiceProvider)
            If (MyBase.Parent Is Nothing) Then
                Throw New InvalidOperationException(SR.GetString("Error_MustHaveParent"))
            End If
            MyBase.Initialize(provider)
        End Sub

        Private Function System.Workflow.ComponentModel.Design.ITypeFilterProvider.CanFilterType(ByVal type As Type, ByVal throwOnError As Boolean) As Boolean Implements ITypeFilterProvider.CanFilterType
            Dim flag As Boolean = TypeProvider.IsAssignable(GetType(Exception), type)
            If (throwOnError AndAlso Not flag) Then
                Throw New Exception(SR.GetString("Error_ExceptionTypeNotException", New Object() { type, "Type" }))
            End If
            Return flag
        End Function

        Private Function System.Workflow.ComponentModel.IDynamicPropertyTypeProvider.GetAccessType(ByVal serviceProvider As IServiceProvider, ByVal propertyName As String) As AccessTypes Implements IDynamicPropertyTypeProvider.GetAccessType
            Return AccessTypes.Read
        End Function

        Private Function System.Workflow.ComponentModel.IDynamicPropertyTypeProvider.GetPropertyType(ByVal serviceProvider As IServiceProvider, ByVal propertyName As String) As Type Implements IDynamicPropertyTypeProvider.GetPropertyType
            If (Not String.IsNullOrEmpty(propertyName) AndAlso propertyName.Equals("Fault", StringComparison.Ordinal)) Then
                Return Me.FaultType
            End If
            Return Nothing
        End Function


        ' Properties
        <TypeConverter(GetType(FaultConverter)), DefaultValue(CStr(Nothing)), SRCategory("Handlers"), SRDescription("FaultDescription"), MergableProperty(False)> _
        Public Property Fault As Exception
            Get
                Return [TryCast](MyBase.GetValue(ThrowActivity.FaultProperty),Exception)
            End Get
            Set(ByVal value As Exception)
                MyBase.SetValue(ThrowActivity.FaultProperty, value)
            End Set
        End Property

        <MergableProperty(False), TypeConverter(GetType(FaultTypeConverter)), SRDescription("FaultTypeDescription"), DefaultValue(CStr(Nothing)), Editor(GetType(TypeBrowserEditor), GetType(UITypeEditor)), SRCategory("Handlers")> _
        Public Property FaultType As Type
            Get
                Return [TryCast](MyBase.GetValue(ThrowActivity.FaultTypeProperty),Type)
            End Get
            Set(ByVal value As Type)
                MyBase.SetValue(ThrowActivity.FaultTypeProperty, value)
            End Set
        End Property

        Private ReadOnly Property System.Workflow.ComponentModel.Design.ITypeFilterProvider.FilterDescription As String
            Get
                Return SR.GetString("FilterDescription_FaultHandlerActivity")
            End Get
        End Property


        ' Fields
        <Browsable(False)> _
        Public Shared ReadOnly FaultProperty As DependencyProperty = DependencyProperty.Register("Fault", GetType(Exception), GetType(ThrowActivity))
        <Browsable(False)> _
        Public Shared ReadOnly FaultTypeProperty As DependencyProperty = DependencyProperty.Register("FaultType", GetType(Type), GetType(ThrowActivity))

        ' Nested Types
        Private NotInheritable Class FaultConverter
            Inherits TypeConverter
            ' Methods
            Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
                If (sourceType Is GetType(String)) Then
                    Return False
                End If
                Return MyBase.CanConvertFrom(context, sourceType)
            End Function

        End Class

        Private NotInheritable Class FaultTypeConverter
            Inherits TypeConverter
            ' Methods
            Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
                Return ((sourceType Is GetType(String)) OrElse MyBase.CanConvertFrom(context, sourceType))
            End Function

            Public Overrides Function CanConvertTo(ByVal context As ITypeDescriptorContext, ByVal destinationType As Type) As Boolean
                Return ((destinationType Is GetType(String)) OrElse MyBase.CanConvertTo(context, destinationType))
            End Function

            Public Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object) As Object
                Dim obj2 As Object = value
                Dim str As String = [TryCast](value,String)
                Dim service As ITypeProvider = [TryCast](context.GetService(GetType(ITypeProvider)),ITypeProvider)
                If (((Not context Is Nothing) AndAlso (Not service Is Nothing)) AndAlso Not String.IsNullOrEmpty(str)) Then
                    Dim type As Type = service.GetType(str, False)
                    If (type Is Nothing) Then
                        Return obj2
                    End If
                    Dim instance As ITypeFilterProvider = [TryCast](context.Instance,ITypeFilterProvider)
                    If (Not instance Is Nothing) Then
                        instance.CanFilterType(type, True)
                    End If
                    Return type
                End If
                If ((Not str Is Nothing) AndAlso (str.Length = 0)) Then
                    obj2 = Nothing
                End If
                Return obj2
            End Function

            Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
                If (destinationType Is GetType(String)) Then
                    Dim type As Type = [TryCast](value,Type)
                    If (Not type Is Nothing) Then
                        Return type.FullName
                    End If
                End If
                Return MyBase.ConvertTo(context, culture, value, destinationType)
            End Function

        End Class
    End Class
End Namespace

